// 性能优化工具集

/**
 * 防抖函数
 * @param {Function} func 要防抖的函数
 * @param {Number} wait 防抖延迟时间
 * @param {Boolean} immediate 是否立即执行
 */
export function debounce(func, wait, immediate = false) {
  let timeout
  return function (...args) {
    const context = this
    const later = function () {
      timeout = null
      if (!immediate) func.apply(context, args)
    }
    const callNow = immediate && !timeout
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)
    if (callNow) func.apply(context, args)
  }
}

/**
 * 节流函数
 * @param {Function} func 要节流的函数
 * @param {Number} wait 节流间隔时间
 */
export function throttle(func, wait) {
  let timeout
  let previous = 0
  
  return function (...args) {
    const context = this
    const now = Date.now()
    const remaining = wait - (now - previous)
    
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }
      previous = now
      func.apply(context, args)
    } else if (!timeout) {
      timeout = setTimeout(() => {
        previous = Date.now()
        timeout = null
        func.apply(context, args)
      }, remaining)
    }
  }
}

/**
 * 图片懒加载
 * @param {String} src 图片地址
 * @param {Object} options 配置选项
 */
export function lazyLoadImage(src, options = {}) {
  const {
    placeholder = '/static/placeholder.png',
    errorImage = '/static/error.png',
    quality = 80,
    maxWidth = 800,
    maxHeight = 600
  } = options
  
  return new Promise((resolve, reject) => {
    if (!src) {
      resolve(placeholder)
      return
    }
    
    // 预加载图片
    const img = new Image()
    img.onload = () => {
      resolve(optimizeImageUrl(src, { quality, maxWidth, maxHeight }))
    }
    img.onerror = () => {
      console.warn('图片加载失败:', src)
      resolve(errorImage)
    }
    img.src = src
  })
}

/**
 * 优化图片URL（添加压缩参数）
 * @param {String} url 原始图片URL
 * @param {Object} options 压缩选项
 */
export function optimizeImageUrl(url, options = {}) {
  if (!url || typeof url !== 'string') return url
  
  const {
    quality = 80,
    maxWidth = 800,
    maxHeight = 600,
    format = 'webp'
  } = options
  
  // 本地图片不处理
  if (url.startsWith('/static/') || url.startsWith('data:') || url.startsWith('blob:')) {
    return url
  }
  
  // 七牛云
  if (url.includes('qiniu.com') || url.includes('clouddn.com')) {
    return `${url}?imageView2/2/w/${maxWidth}/h/${maxHeight}/q/${quality}/format/${format}`
  }
  
  // 阿里云OSS
  if (url.includes('aliyuncs.com')) {
    return `${url}?x-oss-process=image/resize,w_${maxWidth},h_${maxHeight}/quality,q_${quality}/format,${format}`
  }
  
  // 腾讯云COS
  if (url.includes('myqcloud.com')) {
    return `${url}?imageView2/2/w/${maxWidth}/h/${maxHeight}/q/${quality}/format/${format}`
  }
  
  return url
}

/**
 * 缓存管理
 */
export class Cache {
  constructor(prefix = 'mvr_cache_') {
    this.prefix = prefix
    this.maxSize = 50 // 最大缓存条目数
  }
  
  // 设置缓存
  set(key, value, expireTime = 3600000) { // 默认1小时过期
    const data = {
      value,
      expireTime: Date.now() + expireTime,
      timestamp: Date.now()
    }
    
    try {
      uni.setStorageSync(this.prefix + key, JSON.stringify(data))
      this.cleanExpired()
    } catch (error) {
      console.warn('缓存设置失败:', error)
    }
  }
  
  // 获取缓存
  get(key) {
    try {
      const dataStr = uni.getStorageSync(this.prefix + key)
      if (!dataStr) return null
      
      const data = JSON.parse(dataStr)
      
      // 检查是否过期
      if (Date.now() > data.expireTime) {
        this.remove(key)
        return null
      }
      
      return data.value
    } catch (error) {
      console.warn('缓存获取失败:', error)
      return null
    }
  }
  
  // 移除缓存
  remove(key) {
    try {
      uni.removeStorageSync(this.prefix + key)
    } catch (error) {
      console.warn('缓存移除失败:', error)
    }
  }
  
  // 清理过期缓存
  cleanExpired() {
    try {
      const info = uni.getStorageInfoSync()
      const keys = info.keys.filter(key => key.startsWith(this.prefix))
      
      keys.forEach(key => {
        const dataStr = uni.getStorageSync(key)
        if (dataStr) {
          try {
            const data = JSON.parse(dataStr)
            if (Date.now() > data.expireTime) {
              uni.removeStorageSync(key)
            }
          } catch (error) {
            // 删除无效缓存
            uni.removeStorageSync(key)
          }
        }
      })
      
      // 如果缓存条目过多，删除最旧的
      if (keys.length > this.maxSize) {
        const validKeys = info.keys
          .filter(key => key.startsWith(this.prefix))
          .map(key => {
            const dataStr = uni.getStorageSync(key)
            try {
              const data = JSON.parse(dataStr)
              return { key, timestamp: data.timestamp }
            } catch {
              return null
            }
          })
          .filter(Boolean)
          .sort((a, b) => a.timestamp - b.timestamp)
        
        const toDelete = validKeys.slice(0, validKeys.length - this.maxSize)
        toDelete.forEach(item => uni.removeStorageSync(item.key))
      }
    } catch (error) {
      console.warn('清理缓存失败:', error)
    }
  }
  
  // 清空所有缓存
  clear() {
    try {
      const info = uni.getStorageInfoSync()
      const keys = info.keys.filter(key => key.startsWith(this.prefix))
      keys.forEach(key => uni.removeStorageSync(key))
    } catch (error) {
      console.warn('清空缓存失败:', error)
    }
  }
}

// 创建全局缓存实例
export const globalCache = new Cache()

/**
 * 性能监控
 */
export class PerformanceMonitor {
  constructor() {
    this.marks = new Map()
    this.measures = new Map()
  }
  
  // 标记开始时间
  mark(name) {
    this.marks.set(name, Date.now())
  }
  
  // 测量时间差
  measure(name, startMark) {
    const startTime = this.marks.get(startMark)
    if (startTime) {
      const duration = Date.now() - startTime
      this.measures.set(name, duration)
      console.log(`性能测量 [${name}]: ${duration}ms`)
      return duration
    }
    return 0
  }
  
  // 获取测量结果
  getMeasure(name) {
    return this.measures.get(name)
  }
  
  // 清除标记
  clearMarks() {
    this.marks.clear()
  }
  
  // 清除测量
  clearMeasures() {
    this.measures.clear()
  }
  
  // 获取页面性能信息
  getPagePerformance() {
    const systemInfo = uni.getSystemInfoSync()
    return {
      platform: systemInfo.platform,
      model: systemInfo.model,
      windowWidth: systemInfo.windowWidth,
      windowHeight: systemInfo.windowHeight,
      pixelRatio: systemInfo.pixelRatio,
      screenWidth: systemInfo.screenWidth,
      screenHeight: systemInfo.screenHeight,
      statusBarHeight: systemInfo.statusBarHeight,
      navBarHeight: systemInfo.navBarHeight,
      timestamp: Date.now()
    }
  }
}

// 创建全局性能监控实例
export const perfMonitor = new PerformanceMonitor()

/**
 * 内存管理
 */
export function clearMemory() {
  // 清理全局缓存
  globalCache.cleanExpired()
  
  // 清理性能监控数据
  perfMonitor.clearMarks()
  perfMonitor.clearMeasures()
  
  // 触发垃圾回收（如果支持）
  if (typeof gc === 'function') {
    gc()
  }
  
  console.log('内存清理完成')
}

/**
 * 批量操作优化
 * @param {Array} items 要处理的项目数组
 * @param {Function} processor 处理函数
 * @param {Number} batchSize 批处理大小
 */
export function batchProcess(items, processor, batchSize = 10) {
  return new Promise((resolve) => {
    let index = 0
    const results = []
    
    function processBatch() {
      const batch = items.slice(index, index + batchSize)
      
      batch.forEach((item, i) => {
        results[index + i] = processor(item, index + i)
      })
      
      index += batchSize
      
      if (index < items.length) {
        setTimeout(processBatch, 0) // 异步处理下一批
      } else {
        resolve(results)
      }
    }
    
    processBatch()
  })
}

/**
 * 智能预加载
 * @param {Array} urls 要预加载的URL数组
 * @param {Number} concurrency 并发数
 */
export async function preloadImages(urls, concurrency = 3) {
  const results = []
  const executing = []
  
  for (const url of urls) {
    const promise = lazyLoadImage(url).then(optimizedUrl => {
      return { url, optimizedUrl, success: true }
    }).catch(error => {
      return { url, error, success: false }
    })
    
    results.push(promise)
    
    if (urls.length >= concurrency) {
      executing.push(promise)
      
      if (executing.length >= concurrency) {
        await Promise.race(executing)
        executing.splice(executing.findIndex(p => p === promise), 1)
      }
    }
  }
  
  return Promise.all(results)
} 